home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / elv18src.zip / wildcard.c < prev   
C/C++ Source or Header  |  1994-01-10  |  4KB  |  215 lines

  1. /* wildcard.c */
  2.  
  3. /* Author:
  4.  *    Guntram Blohm
  5.  *    Buchenstrasse 19
  6.  *    7904 Erbach, West Germany
  7.  *    Tel. ++49-7305-6997
  8.  *    sorry - no regular network connection
  9.  */
  10.  
  11. /* this program implements wildcard expansion for elvis/dos. It works
  12.  * like UNIX echo, but uses the dos wildcard conventions
  13.  * (*.* matches all files, * matches files without extension only,
  14.  * filespecs may contain drive letters, wildcards not allowed in directory
  15.  * names).
  16.  *
  17.  * It is also #included into ctags.c and elvprsv.c; in this case,
  18.  * we don't want a main function here.
  19.  */
  20.  
  21. #include <stdio.h>
  22. #ifdef __STDC__
  23. # include <stdlib.h>
  24. #endif
  25. #ifndef    WILDCARD_NO_MAIN
  26. # include "config.h"
  27. #endif
  28. #ifdef    __TURBOC__
  29. # include <dir.h>
  30. #endif
  31.  
  32. void    expand P_((char *));
  33. void    addfile P_((char *));
  34.  
  35. /* We include ctype.c here (instead of including just ctype.h and linking
  36.  * with ctype.o) because on some systems ctype.o will have been compiled in
  37.  * "large model" and the wildcard program is to be compiled in "small model" 
  38.  * You can't mix models.  By including ctype.c here, we can avoid linking
  39.  * with ctype.o.
  40.  *
  41.  * HOWEVER, if WILDCARD_NO_MAIN is defined then wildcard.c is itself being
  42.  * included in another .c file, which has either already included ctypes.c or
  43.  * will be linked with ctypes.o, so in this instance we include just ctypos.h.
  44.  */
  45. #ifdef WILDCARD_NO_MAIN
  46. # include "ctype.h"
  47. #else
  48. # include "ctype.c"
  49. #endif
  50.  
  51. #ifdef    M_I86
  52. # define findfirst(a,b,c)    _dos_findfirst(a,c,b)
  53. # define findnext        _dos_findnext
  54. # define ffblk            find_t
  55. # define ff_name        name
  56. # include <dos.h>
  57. #endif
  58.  
  59. /* Atari TOS, MWC */
  60. #ifdef M68000
  61. # include <stat.h>
  62. # include <osbind.h>
  63. # define findfirst(a,b,c)    (Fsetdta(b), (Fsfirst(a,c)))
  64. # define findnext(x)        (Fsnext())
  65. # define ff_name        d_fname
  66. #endif
  67.  
  68. /* Atari TOS, GNU-C */
  69. #ifdef __m68k__
  70. # include <stat.h>
  71. # include <osbind.h>
  72. # define findfirst(a,b,c)    (Fsetdta(b), (Fsfirst(a,c)))
  73. # define findnext(x)        (Fsnext())
  74. # define ff_name        dta_name
  75. # define DMABUFFER         struct _dta
  76. #endif
  77.  
  78. /* OS/2, emx+gcc 0.8x */
  79. #if OS2
  80. # define size_t xxx_size_t
  81. # include <sys/emx.h>
  82. # undef size_t
  83. # define findfirst(a,b,c)    __findfirst(a,c,b)
  84. # define findnext        __findnext
  85. # define ffblk            _find
  86. # define ff_name        name
  87. #endif
  88.  
  89. #define    MAXFILES    1000
  90.  
  91. #if !defined(__STDC__) && !defined(__TURBOC__)
  92. extern char *calloc();
  93. #endif
  94.  
  95. char *files[MAXFILES];
  96. int nfiles;
  97.  
  98. #ifndef    WILDCARD_NO_MAIN
  99.  
  100. main(argc, argv)
  101.     char **argv;
  102. {
  103.     int i;
  104.  
  105.     /* GRR:  for OS/2 and emx+gcc, could use _wildcard() built-in */
  106.  
  107.     _ct_init("");
  108.     for (i=1; i<argc; i++)
  109.         expand(argv[i]);
  110.     if (nfiles)
  111.         printf("%s", files[0]);
  112.     for (i=1; i<nfiles; i++)
  113.     {
  114.         printf(" %s", files[i]);
  115.     }
  116.     putchar('\n');
  117.     return 0;
  118. }
  119.  
  120. #else
  121. char **wildexpand(argc, argv)
  122.     int *argc;
  123.     char **argv;
  124. {
  125.     int i;
  126.     
  127.     /* GRR:  for OS/2 and emx+gcc, could just use _wildcard() built-in */
  128.  
  129.     for (i=0; i<*argc; i++)
  130.         expand(argv[i]);
  131.     *argc=nfiles;
  132.     return files;
  133. }    
  134. #endif
  135.  
  136. #ifdef __TURBOC__
  137. int pstrcmp(const void *a, const void *b)
  138. #else
  139. int pstrcmp(a, b)
  140.     char **a, **b;
  141. #endif
  142. {
  143.     return strcmp(*(char **)a, *(char **)b);
  144. }
  145.  
  146. void expand(name)
  147.     char *name;
  148. {
  149.     char *filespec;
  150.     int wildcard=0;
  151. #if defined(M68000) || defined(__m68k__)
  152.     DMABUFFER findbuf;
  153. #else
  154.     struct ffblk findbuf;
  155. #endif
  156.     int err;
  157.     char buf[80];
  158.     int lastn;
  159.  
  160.     strcpy(buf, name);
  161.     for (filespec=buf; *filespec; filespec++)
  162.         ;
  163.  
  164.     while (--filespec>=buf)
  165.     {    if (*filespec=='?' || *filespec=='*')
  166.             wildcard=1;
  167.         if (*filespec=='/' || *filespec=='\\' || *filespec==':')
  168.             break;
  169.     }
  170.     if (!wildcard)
  171.         addfile(buf);
  172.     else
  173.     {
  174.         lastn=nfiles;
  175.         filespec++;
  176.         if ((err=findfirst(buf, &findbuf, 0))!=0)
  177.             addfile(buf);
  178.         while (!err)
  179.         {
  180.             strcpy(filespec, findbuf.ff_name);
  181.             addfile(buf);
  182.             err=findnext(&findbuf);
  183.         }
  184.         if (lastn!=nfiles)
  185.             qsort(files+lastn, nfiles-lastn, sizeof(char *), pstrcmp);
  186.     }
  187. }
  188.  
  189. #if MINT
  190. extern int __mint;
  191. #endif
  192. void addfile(buf)
  193.     char *buf;
  194. {
  195.     char *p;
  196.  
  197. #if MINT
  198.     /* there are filesystems on MiNT that are case sensitive... and for
  199.      * the vanilla GEMDOS fs MiNT already does this conversion itself.
  200.      */
  201.     if (!__mint)
  202. #endif
  203. #if !OS2
  204.     for (p=buf; *p; p++)
  205.         *p=tolower(*p);
  206. #endif
  207.     /* convert spaces to something else so not confused with delimiter */
  208.     for (p=buf; *p; p++)
  209.         if (*p == ' ')
  210.             *p = SPACEHOLDER;
  211.  
  212.     if (nfiles<MAXFILES && (files[nfiles]=calloc(strlen(buf)+1, 1))!=0)
  213.         strcpy(files[nfiles++], buf);
  214. }
  215.